//
//  UIView+Corner.m
//

#import "UIView+Corner.h"
#import <objc/runtime.h>
#import "UIColor+Expanded.h"

@implementation UIView (Corner)

static const char RoundCornerRad = '\0';
- (void)setRoundCornerRad:(CGFloat)roundCornerRad{
    objc_setAssociatedObject(self, &RoundCornerRad, @(roundCornerRad), OBJC_ASSOCIATION_ASSIGN);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self roundingCornersRad:roundCornerRad];
    });
}

- (CGFloat)roundCornerRad{
    NSNumber *rad = objc_getAssociatedObject(self, &RoundCornerRad);
    return rad.doubleValue;
}

static const char BorderWidth = '\0';
- (void)setBorderWidth:(CGFloat)borderWidth{
    objc_setAssociatedObject(self, &BorderWidth, @(borderWidth), OBJC_ASSOCIATION_ASSIGN);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self addBorder:borderWidth];
    });
}

- (CGFloat)borderWidth{
    NSNumber *width = objc_getAssociatedObject(self, &BorderWidth);
    return width.doubleValue;
}

static const char BorderColor = '\0';
- (void)setBorderColor:(UIColor *)borderColor{
    objc_setAssociatedObject(self, &BorderColor, borderColor, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (UIColor *)borderColor {
    return objc_getAssociatedObject(self, &BorderColor);
}


#pragma Function

- (void)addBorder:(float)lineWidth{
    
    CALayer *borderLayerOld = nil;
    for (int sub =0; sub<self.layer.sublayers.count; sub++) {
        CALayer *layer = self.layer.sublayers[sub];
        if([layer.name isEqualToString:@"addBorder"]){
            borderLayerOld = layer;
            break;
        }
    }
    (borderLayerOld) ? [borderLayerOld removeFromSuperlayer] : nil;
    
    float width = CGRectGetWidth(self.bounds);
    float height = CGRectGetHeight(self.bounds);
    CAShapeLayer *borderLayer = [CAShapeLayer layer];
    borderLayer.bounds = CGRectMake(0, 0, width, height);
    borderLayer.position = CGPointMake(width/2.0, height/2.0);
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0,width, height)
                            byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight|UIRectCornerBottomLeft|UIRectCornerBottomRight
                            cornerRadii:CGSizeMake(self.roundCornerRad, self.roundCornerRad)];
    borderLayer.path = maskPath.CGPath;
    borderLayer.name = @"addBorder";
    borderLayer.lineWidth =  lineWidth  / [[UIScreen mainScreen] scale];
    borderLayer.fillColor = [UIColor clearColor].CGColor;
    borderLayer.strokeColor = (self.borderColor) ? self.borderColor.CGColor : [UIColor colorWithRGBHexString:@"CCCCCC"].CGColor;
    [self.layer addSublayer:borderLayer];
}

- (void)roundingCornersRad:(CGFloat)radi
{
    if (!radi) {
        self.layer.mask = nil;
        return;
    }
    
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds)) byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight|UIRectCornerBottomLeft|UIRectCornerBottomRight cornerRadii:CGSizeMake(radi, radi)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
    maskLayer.path = maskPath.CGPath;
    self.layer.mask = maskLayer;
}

- (void)roundingCorners:(UIRectCorner)rectCorner withCornerRadii:(CGSize)cornerRadii
{
    if (CGSizeEqualToSize(cornerRadii, CGSizeZero)) {
        self.layer.mask = nil;
        return;
    }
    
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds)) byRoundingCorners:rectCorner cornerRadii:cornerRadii];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
    maskLayer.path = maskPath.CGPath;
    self.layer.mask = maskLayer;
}

- (void)roundingInscribeCorners:(UIRectCorner)rectCorner withCornerRadii:(CGFloat)cornerRadii
{
    if (!cornerRadii) {
        self.layer.mask = nil;
        return;
    }
    
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    bezierPath.lineCapStyle = kCGLineCapRound;
    bezierPath.lineJoinStyle = kCGLineJoinRound;
    
    if ((rectCorner & UIRectCornerTopLeft)) {
        [bezierPath moveToPoint:CGPointMake(cornerRadii, 0.0f)];
    }else {
        [bezierPath moveToPoint:CGPointMake(0.0f, 0.0f)];
    }
    
    if ((rectCorner & UIRectCornerTopRight)) {
        [bezierPath addLineToPoint:CGPointMake(CGRectGetWidth(self.bounds) - cornerRadii, 0.0f)];
        [bezierPath addArcWithCenter:CGPointMake(CGRectGetWidth(self.bounds), 0) radius:cornerRadii startAngle:M_PI endAngle:M_PI_2 clockwise:NO];
    }else {
        [bezierPath addLineToPoint:CGPointMake(CGRectGetWidth(self.bounds), 0.0f)];
    }
    
    if ((rectCorner & UIRectCornerBottomRight)) {
        [bezierPath addLineToPoint:CGPointMake(CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - cornerRadii)];
        [bezierPath addArcWithCenter:CGPointMake(CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds)) radius:cornerRadii startAngle:-M_PI_2 endAngle:M_PI clockwise:NO];
    }else {
        [bezierPath addLineToPoint:CGPointMake(CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
    }
    
    if ((rectCorner & UIRectCornerBottomLeft)) {
        [bezierPath addLineToPoint:CGPointMake(cornerRadii, CGRectGetHeight(self.bounds))];
        [bezierPath addArcWithCenter:CGPointMake(0.0f, CGRectGetHeight(self.bounds)) radius:cornerRadii startAngle:0.0f endAngle:-M_PI_2 clockwise:NO];
    }else {
        [bezierPath addLineToPoint:CGPointMake(0.0f, CGRectGetHeight(self.bounds))];
    }
    
    if ((rectCorner & UIRectCornerTopLeft)) {
        [bezierPath addLineToPoint:CGPointMake(0.0f, cornerRadii)];
        [bezierPath addArcWithCenter:CGPointMake(0.0f, 0.0f) radius:cornerRadii startAngle:M_PI_2 endAngle:0.0f clockwise:NO];
    }else {
        [bezierPath addLineToPoint:CGPointMake(0.0f, 0.0f)];
    }
    
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
    maskLayer.path = bezierPath.CGPath;
    self.layer.mask = maskLayer;
}

- (void)addGaussFuzzyRect:(CGRect)rect withStyle:(UIBlurEffectStyle)blurEffectStyle
{
    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:blurEffectStyle];
    UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    visualEffectView.alpha = 0.9;
    visualEffectView.frame = rect;
    [self addSubview:visualEffectView];
}

- (void)removeGaussFuzzy
{
    for (id view in self.subviews) {
        if ([view isKindOfClass:[UIVisualEffectView class]]) {
            [view removeFromSuperview];
        }
    }
}


- (UIImage *)screenshots
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
    [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

- (void)addShadwCorners:(UIRectEdge)rectEdge
                  fillColor:(UIColor *)fillColor
            cornerRadii:(CGSize)cornerRadii{
    
    UIBezierPath *pathShadow = [UIBezierPath bezierPathWithRect:CGRectMake(3, 3,
                                                                                  self.bounds.size.width-6,
                                                                                  self.bounds.size.height-6)
                                                ];

    pathShadow.lineCapStyle = kCGLineCapRound;
    pathShadow.lineJoinStyle = kCGLineJoinRound;
    pathShadow.lineWidth = 5.0;

    CAShapeLayer *shadowLayer = [[CAShapeLayer alloc] init];
    shadowLayer.frame = CGRectMake(0, 0, CGRectGetWidth(self.bounds)-6, CGRectGetHeight(self.bounds));
    shadowLayer.path = pathShadow.CGPath;
    shadowLayer.shadowColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.4].CGColor;
    shadowLayer.shadowOffset = CGSizeMake(0, 0);
    shadowLayer.shadowOpacity = 1;
    shadowLayer.shadowRadius = 3;
    shadowLayer.fillColor = self.backgroundColor.CGColor;

    [self.layer addSublayer:shadowLayer];

}

@end
